package com.xbongbong.crm.service.permission;

import com.xbongbong.paas.constant.PaasConstant;
import com.xbongbong.paas.domain.entity.ext.PaasFormDataEntityExt;
import com.xbongbong.paas.domain.entity.ext.PaasFormEntityExt;
import com.xbongbong.paas.enums.DelEnum;
import com.xbongbong.paas.toolbox.exception.XbbException;
import com.xbongbong.paas.toolbox.wrap.DepartmentVO;
import com.xbongbong.paas.toolbox.wrap.RoleSimpleVO;
import com.xbongbong.paas.toolbox.wrap.UserVO;
import com.xbongbong.parent.abstracts.AbstractBusinessPermissionService;
import com.xbongbong.pro.enums.errorcodes.SystemErrorCodeEnum;
import com.xbongbong.pro.permission.pojo.dto.VerifyViewPermissionDTO;
import com.xbongbong.saas.constant.BasicConstant;
import com.xbongbong.saas.constant.StringConstant;
import com.xbongbong.saas.enums.XbbRefTypeEnum;
import com.xbongbong.saas.model.WorkReportApprovePeopleModel;
import com.xbongbong.saas.model.WorkReportCcModel;
import com.xbongbong.sys.model.UserModel;
import com.xbongbong.sys.util.UserPermissionUtil;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Set;

/**
 * @author sunshaoxiang
 * @ClassName WorkReportPermissionServiceImpl
 * @Description 工作报告权限 Service
 * @Date 2022/6/23 11:03
 * @Version 1.0
 **/
@Service
public class WorkReportPermissionServiceImpl extends AbstractBusinessPermissionService<PaasFormDataEntityExt, PaasFormEntityExt> {
    @Resource
    private UserModel userModel;
    @Resource
    private WorkReportApprovePeopleModel workReportApprovePeopleModel;
    @Resource
    private WorkReportCcModel workReportCcModel;

    @Override
    public List<Integer> businessType() {
        return Collections.singletonList(XbbRefTypeEnum.WORK_REPORT.getCode());
    }



    @Override
    public void checkPermission(PaasFormEntityExt formEntity, PaasFormDataEntityExt paasFormDataEntityExt, UserVO loginUser, Integer subBusinessType) throws XbbException {
        if (UserPermissionUtil.isMaxDataPermission(loginUser, formEntity.getSaasMark(), XbbRefTypeEnum.WORK_REPORT.getCode(), formEntity.getDistributorMark(), formEntity.getMenuId(), false)){
            return;
        }

        Integer dataPermission = userModel.getDataPermission(loginUser, false);
        List<String> userIdIn = userModel.getSubIdListByDataPermission(dataPermission, loginUser.getUserId(), loginUser.getCorpid(), BasicConstant.ZERO,false);
        VerifyViewPermissionDTO verifyViewPermissionDTO = new VerifyViewPermissionDTO(loginUser, paasFormDataEntityExt);
        boolean hasDataPermission = checkWorkReport(paasFormDataEntityExt, loginUser, userIdIn)
                || sharePermissionHelp.verifySharePermission4QueryWithRuleEngine(verifyViewPermissionDTO);
        if (!hasDataPermission) {
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100017);
        }
    }

    @Override
    public boolean hasPermission(PaasFormEntityExt formEntity, PaasFormDataEntityExt paasFormDataEntityExt, UserVO loginUser, Integer subBusinessType) throws XbbException {
        if (UserPermissionUtil.isMaxDataPermission(loginUser, formEntity.getSaasMark(), XbbRefTypeEnum.WORK_REPORT.getCode(), formEntity.getDistributorMark(), formEntity.getMenuId(), false)){
            return true;
        }

        Integer dataPermission = userModel.getDataPermission(loginUser, false);
        List<String> userIdIn = userModel.getSubIdListByDataPermission(dataPermission, loginUser.getUserId(), loginUser.getCorpid(), BasicConstant.ZERO,false);
        return checkWorkReport(paasFormDataEntityExt, loginUser ,userIdIn);

    }

    /**
     * 我发的,发我的,抄我的
     * 重构前 -> com.xbongbong.saas.help.SaasDetailPermissionHelp#checkWorkReport(com.xbongbong.paas.domain.entity.ext.PaasFormDataEntityExt, com.xbongbong.paas.toolbox.wrap.UserVO, java.util.List)
     * @param paasFormDataEntityExt
     * @param userVO
     * @param userIdIn
     * @throws XbbException
     */
    private boolean checkWorkReport(PaasFormDataEntityExt paasFormDataEntityExt, UserVO userVO, List<String> userIdIn) throws XbbException{
        String corpid = userVO.getCorpid();
        String userId = userVO.getUserId();
        if (Objects.equals(paasFormDataEntityExt.getCreatorId(),userId)){
            return true;
        }
        if (userIdIn.contains(paasFormDataEntityExt.getCreatorId())){
            return true;
        }
        // 发我的
        Set<DepartmentVO> departmentVOSet = userVO.getDepSet();
        Set<RoleSimpleVO> roleSimpleVOSet = userVO.getRoleSet();
        List<String> deptIdIn = new ArrayList<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        List<String> roleIdIn = new ArrayList<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        List<String> userIds = Arrays.asList(userId);
        if (!CollectionUtils.isEmpty(departmentVOSet)){
            for (DepartmentVO item : departmentVOSet) {
                deptIdIn.add(item.getId().toString());
            }
        }
        if (!CollectionUtils.isEmpty(roleSimpleVOSet)){
            for (RoleSimpleVO item : roleSimpleVOSet) {
                roleIdIn.add(item.getId().toString());
            }
        }
        Map<String,Object> param = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        param.put("corpid",corpid);
        param.put("userIdIn", CollectionUtils.isEmpty(userIds) ? null : userIds);
        param.put("deptIdIn",CollectionUtils.isEmpty(deptIdIn) ? null : deptIdIn);
        param.put("roleIdIn",CollectionUtils.isEmpty(roleIdIn) ? null : roleIdIn);
        param.put("reportId",paasFormDataEntityExt.getId());
        param.put(StringConstant.DEL, DelEnum.NORMAL.getDel());
        param.put("order by", "report_id desc");
        Integer approvePeopleCount = workReportApprovePeopleModel.getEntitysCount(param);
        // 抄我的
        param.clear();
        param.put("corpid",corpid);
        param.put("reportId",paasFormDataEntityExt.getId());
        param.put("userId",userId);
        param.put("del",0);
        Integer count = workReportCcModel.getEntitysCount(param);
        return approvePeopleCount > 0 || count > 0;


    }
}
